package com.peycard.util;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;

import javax.imageio.ImageIO;
import javax.persistence.PersistenceException;

import org.springframework.stereotype.Component;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfShading;
import com.itextpdf.text.pdf.PdfWriter;
import com.peycard.common.CompanyDTO;
import com.peycard.common.FinancialTransactionsDTO;
import com.peycard.common.ReaderDTO;

@Component
public class TransactionReceipt {

	public void generaPDF(OutputStream outputStream,
			FinancialTransactionsDTO transaction) throws Exception {
		Document documento = new Document();
		PdfWriter writer = PdfWriter.getInstance(documento, outputStream);
		documento.open();
		documento.addTitle("Recibo");
		PdfContentByte cb = writer.getDirectContent();
		PdfGState gs1 = new PdfGState();
		documento.setMargins(32, 32, 32, 32);
		printFondo(writer, cb, gs1);
		printRectangulo(cb, gs1);
		printEncabezado(cb, gs1, transaction);
		printDatos(cb, gs1, transaction);
		printFirma(cb, gs1, transaction);
		printMapa(cb, gs1, transaction);
		documento.close();
		outputStream.close();
	}

	private void printFondo(PdfWriter writer, PdfContentByte cb, PdfGState gs1) {
		gs1.setFillOpacity(0.1f);
		cb.setGState(gs1);
		cb.saveState();
		PdfShading axial = PdfShading.simpleAxial(writer, 50, 100, 50, 50,
				BaseColor.WHITE, BaseColor.BLUE);
		cb.paintShading(axial);
		cb.restoreState();
	}

	private void printEncabezado(PdfContentByte cb, PdfGState gs1,
			FinancialTransactionsDTO pago) throws DocumentException {
		SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMMyy");
		SimpleDateFormat hourFormat = new SimpleDateFormat("HH:mm");

		gs1.setFillOpacity(1.0f);
		cb.setGState(gs1);
		/*ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				comercio.getTradename().toUpperCase()), 290, 790, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				comercio.getStreet() + " " + comercio.getSuburb() + " "
						+ comercio.getState()), 290, 770, 0);*/
		/*
		 * ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
		 * dispositivo.getNoAfiliacion()), 230, 750, 0);
		 */
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				"Número de terminal".toUpperCase()), 340, 750, 0);
		/* Fecha de la transaccion formato = ddMMMyy */
		ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("FECHA: "
				+ dateFormat.format(pago.getDateTimeTx())), 100, 730, 0);
		/* Hora de la transaccion formato = HH:mm */
		ColumnText.showTextAligned(cb, Element.ALIGN_RIGHT, new Phrase("HORA: "
				+ hourFormat.format(pago.getDateTimeTx())), 500, 730, 0);
	}

	private void printRectangulo(PdfContentByte cb, PdfGState gs1) {
		cb.setCMYKColorFill(600, 10, 20, 20);
		cb.roundRectangle(50, 720, 500, 100, 10);
		cb.fill();
		cb.setCMYKColorFill(600, 10, 20, 0);
		cb.roundRectangle(50, 680, 500, 25, 10);
		cb.fill();
		cb.setCMYKColorFill(600, 10, 20, 0);
		cb.roundRectangle(50, 640, 500, 25, 10);
		cb.fill(); //
		cb.setCMYKColorFill(600, 10, 20, 0);
		cb.roundRectangle(50, 500, 500, 120, 10);
		cb.fill();
		cb.setCMYKColorFill(600, 20, 20, 30);
		cb.roundRectangle(90, 570, 180, 25, 5);
		cb.fill();
		cb.setCMYKColorFill(600, 20, 20, 30);
		cb.roundRectangle(330, 570, 180, 25, 5);
		cb.fill();
		/*
		 * cb.setCMYKColorFill(600, 20, 20, 30); cb.roundRectangle(90, 642, 180,
		 * 20, 5); cb.fill(); cb.setCMYKColorFill(600, 20, 20, 30);
		 * cb.roundRectangle(330, 642, 180, 20, 5); cb.fill();
		 */
		cb.setCMYKColorFill(600, 20, 20, 30);
		cb.roundRectangle(90, 528, 180, 13, 5);
		cb.fill();
		cb.setCMYKColorFill(600, 20, 20, 30);
		cb.roundRectangle(90, 512, 180, 13, 5);
		cb.fill();
		cb.setCMYKColorFill(600, 10, 20, 20);
		cb.roundRectangle(50, 604, 500, 18, 5);
		cb.fill();
		cb.setColorFill(BaseColor.BLUE);
		cb.roundRectangle(180, 340, 240, 2, 1);
		cb.fill();
		cb.setColorFill(BaseColor.BLACK);
		cb.rectangle(47, 128, 510, 190);
		cb.fill();
	}

	public Image obtenerFirma(FinancialTransactionsDTO operation)
			throws FileNotFoundException, BadElementException,
			MalformedURLException, IOException {
		Image image = null;
		byte[] firma = operation.getSign();
		image = Image.getInstance(firma);
		return image;
	}

	private void printFirma(PdfContentByte cb, PdfGState gs1,
			FinancialTransactionsDTO operation) throws DocumentException,
			PersistenceException, FileNotFoundException, MalformedURLException,
			IOException {
		gs1.setFillOpacity(1.0f);
		cb.setGState(gs1);
		cb.saveState();
		Image img = obtenerFirma(operation);
		if (img != null) {
			img.scaleAbsoluteHeight(100);
			img.scaleAbsoluteWidth(200);
			img.setAlignment(Image.ALIGN_CENTER);
			img.setBorder(20);
			img.setBorderColor(BaseColor.BLACK);
			img.setAbsolutePosition(200, 350);
			cb.addImage(img);
		}
		cb.restoreState();
	}

	private void printMapa(PdfContentByte cb, PdfGState gs1,
			FinancialTransactionsDTO pago) throws IOException,
			DocumentException {

		gs1.setFillOpacity(1.0f);
		cb.setGState(gs1);
		cb.saveState();
		double x = pago.getLatitude();
		double y = pago.getLongitude();
		URL url = new URL("http://maps.google.com/maps/api/staticmap?center="
				+ String.valueOf(x) + "," + String.valueOf(y)
				+ "&zoom=16&size=500x180&sensor=true&format=jpg");
		BufferedImage bi = ImageIO.read(url);
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		try {
			ImageIO.write(bi, "jpeg", stream);
		} catch (IOException ex) {
			System.err.println("Error: " + ex.getMessage());
		}
		Image mapa2 = Image.getInstance(stream.toByteArray());
		mapa2.setAlignment(Image.ALIGN_CENTER);
		mapa2.setBorder(20);
		mapa2.setBorderColor(BaseColor.BLACK);
		mapa2.setAbsolutePosition(52, 133);
		cb.addImage(mapa2);
		cb.restoreState();
	}

	private void printDatos(PdfContentByte cb, PdfGState gs1,
			FinancialTransactionsDTO operation) throws DocumentException {
		gs1.setFillOpacity(0.1f);
		cb.setGState(gs1);
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				operation.getPan()), 290, 690, 0);
		/*
		 * ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase("VENC "
		 * + operation.getFechaExp()), 100, 650, 0);
		 */
		ColumnText.showTextAligned(cb, Element.ALIGN_RIGHT, new Phrase(
				"BBVA BANCOMER CREDITO"), 500, 650, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER,
				new Phrase("PAGO"), 290, 610, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
				"TOTAL M.N. "), 100, 580, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_RIGHT, new Phrase("$"
				+ operation.getAmount().toString()), 500, 580, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
				"APROBACIÓN: " + operation.getNoAut()), 100, 530, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_LEFT, new Phrase(
				"ARQC: E47BF856EDEB5B31"), 100, 515, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_JUSTIFIED, new Phrase(
				"FIRMA"), 130, 350, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				"NOMBRE DEL TARJETAHABIENTE"), 300, 330, 0);
		ColumnText.showTextAligned(cb, Element.ALIGN_CENTER, new Phrase(
				"PAGARE NEGOCIABLE UNICAMENTE CON INSTITUCIONES DE CREDITO"),
				300, 110, 0);
	}
}
